//******************************************************************************
//
// ATM系统 -  Session.java 
// 参考了 http://www.cs.gordon.edu/courses/cs211/ATMExample/index.html
// 
//******************************************************************************

package atm;

import banking.Account;
import banking.Retain;
import banking.Transaction;

/**
* 一个Session对象代表了现实世界里的一个人与ATM机器的对话过程.
* @author  何希
* @version 10/06/2018
*/
/*
* @author 莫东林
* @version 2018/11/13
*/
public class Session {

	public static final int NOTREADY = 1; // 未开始
	public static final int AUTHENTICATION = 2; // 待验证 
	public static final int CHOOSING = 3; // 交易选择
	public static final int INTRANSACTION = 4; // 交易中
	public static final int QUIT = 5; // 退出
	public static final int QUIT_WITH_CARD = 6; // 拔卡退出
	public static final int QUIT_WITHOUT_CARD = 7; // 留卡退出
	
	public static final int BACK = 9; //返回操作 
	// 账号
	private String cardNo = null;
	// 密码
	private String pwd = null;
	// 会话的状态
	private int state = NOTREADY;
	// 此会话对应的账户
	private Account acct = null;
	// 当前的交易
	private Transaction trans = null;
	//密码错误次数
	private int pwdFailCount;
	
	public void setState(int state) {
		this.state = state;
	}
	
	public int getState() {
		return state;
	}

	public Account getAccount() {
		return this.acct;
	}
	
	public Transaction getTransaction() {
		return trans;
	}
	
	public void setTransaction(Transaction trans) {
		this.trans = trans;
	}
	
	
	public int getPwdFailCount() {
		return pwdFailCount;
	}

	public void setPwdFailCount(int pwdFailCount) {
		this.pwdFailCount = pwdFailCount;
	}

	/**
	 * 重新开始一个新会话
	 */
	public void startOver() {
		state = NOTREADY;
		cardNo = null;
		pwd = null;
		acct = null;
	}
	
	/**
	 * 确定银行卡是否有效。需要和后台数据库进行比较.
	 * 现在的实现假设银行卡是有效的。
	 * @param cardNo
	 * @return 银行卡是否正确。 0有此卡 1无此卡 2卡被吞
	 * @throws Exception 
	 */
	public int verify(String card_no) throws Exception {
		if(Account.checkCardNo(card_no)){
			//查询是否被吞卡
			if(Retain.checkRetain(card_no)){
				return 2;
			}
			this.cardNo = card_no;
			this.state = AUTHENTICATION;
			return 0;
		}
		return 1;
		
	}
	
	
	/**
	 * 验证银行卡密码
	 * @throws Exception 
	 */
	public void auth(String pwd) throws Exception {
		if(state ==  AUTHENTICATION) {
			this.pwd = pwd;
			this.acct =  Account.getAccount(this.cardNo, this.pwd);
			// 账户密码正确
			if(this.acct != null) {
				state = CHOOSING;
				ATM instance = ATM.getInstance();
				instance.enterMenu();
				//关闭插卡口
				instance.getCardSlot().setInserted(true);
			}
			// 账户密码不正确
			else {
				//密码错误次数加1
				pwdFailCount++;
				ATM instance = ATM.getInstance();
				//错误次数超过3
				if(pwdFailCount > 3){
					instance.getDisplay().setText("密码错误超过3次！吞卡");
					instance.getDigitButton().enterForbidInput("AuthServlet");
					//开启插卡口，可插入其它卡
					instance.getCardSlot().eject();
					//吞卡状态不可操作了 可视为空闲状态 把ATM机置为空闲
					instance.setState(ATM.IDLE);
					//密码错误次数置为0
					pwdFailCount = 0;
					//保存吞卡记录
					Retain.retain(this.cardNo);
				}else{
					instance.getDisplay().setText("密码错误" + pwdFailCount + "次！"+ "请重新输入密码(超过三次则吞卡)");
					instance.getDigitButton().enterHideMultiInput("AuthServlet");
					instance.getCardSlot().setInserted(true);
				}
			}
		}
	}
	
	/**
	 * 选择交易
	 */
	public void selectTransaction(int options) {
		if(state == CHOOSING) {
			this.trans = Transaction.makeTransaction( this, this.acct, options);
			state = INTRANSACTION;
			//如果选项有误，则返回
			if(this.trans == null){
				state = CHOOSING;
			}
		}
	}
	
	/**
	 * 选择 退卡/返回/取消
	 * 返回正常来说是返回主菜单 业务选择
	 */
	public void selectOption(int option){
		switch(option){
		case QUIT:
			ATM.getInstance().clear();
			break;
		case BACK:
			ATM.getInstance().enterMenu();
			break;
		}
	}
	
	/**
	 * 获取Session的状态字符串
	 */
	public String toString() {
		String output = "{";
		output += "\"state\":" + this.state;
		output += "}";
		return output;
	}
}
